<?php

namespace App\Http\Controllers;

use App\Exceptions\AppException;
use App\Exceptions\AuthException;
use App\Jobs\SendSms;
use App\Libs\Sms\Sms;
use App\Models\SubTask;
use App\Models\Task;
use App\Services\TaskService;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;

class TaskController extends Controller
{
    public function list(Request $request)
    {
        $request->validate([
            'name' => 'nullable|string',
            'status' => 'nullable|in:1,2,3,4,5',
            'frequency' => 'nullable|in:monthly,once',
            'page' => 'nullable|integer|min:1',
            'per_page' => 'nullable|integer',
        ]);

        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        $query = Task::query();
        if ($request->name) {
            $query->where('name', 'like', "%{$request->name}%");
        }
        if ($request->status) {
            $query->where('status', $request->status);
        }
        if ($request->frequency) {
            $query->where('frequency', $request->frequency);
        }
        $res = $query->orderBy('id', 'desc')->paginate($request->per_page);
        Arr::map($res->items(), function ($v) {
            $v->setAppends(['progressing', 'districts']);
        });
        return responder()->success($res);
    }

    public function show(Request $request)
    {
        $request->validate([
            'id' => 'required|integer|exists:tasks,id,deleted_at,NULL',
        ]);

        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        $res = Task::with('subTasks.district')->find($request->id);
        $res->setAppends(['progressing', 'districts']);
        $res->subTasks->each(function ($st) {
            $st->makeHidden('data');
            $st->setAppends(['report_log', 'review1_log']);
        });
        return responder()->success($res);
    }

    public function publish(Request $request)
    {
        $request->validate([
            'id' => 'required|integer|exists:tasks,id,deleted_at,NULL',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after:start_date',
            'district_ids.*' => 'required|integer|exists:districts,id,deleted_at,NULL',
        ]);

        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        TaskService::publish(Task::find($request->id), $request->start_date, $request->end_date, $request->district_ids);
        return responder()->success();
    }

    public function remind(Request $request)
    {
        $request->validate([
            'sub_task_ids.*' => 'required|integer|exists:sub_tasks,id,deleted_at,NULL',
        ]);

        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        $sts = SubTask::whereIn('id', $request->sub_task_ids)->get();
        foreach ($sts as $st) {
            if (is_null($st->last_reminded_at) || today() > $st->last_reminded_at) {
                if ($st->status == SubTask::STATUS_INITIALIZED) {
                    $phones = TaskService::nextOperatorPhones($st);
                    SendSms::dispatch($phones, Sms::TMPL4, [TaskService::getSmsTmplTitle($st)]);
                }
                if ($st->status == SubTask::STATUS_WAIT_REVIEW1) {
                    $phones = TaskService::nextOperatorPhones($st);
                    SendSms::dispatch($phones, Sms::TMPL5, [TaskService::getSmsTmplTitle($st)]);
                }

                $st->last_reminded_at = now();
                $st->save();
            } else {
                throw new AppException($st->district->name . ' 今天已经提醒过了');
            }
        }
        return responder()->success();
    }

    public function revoke(Request $request)
    {
        $request->validate([
            'id' => 'required|integer|exists:tasks,id,deleted_at,NULL',
        ]);

        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        $task = Task::find($request->id);
        if ($task->status == Task::STATUS_COMPLETED) {
            throw new AppException('已完成的任务无法撤回');
        }
        $task->subTasks()->delete();
        $task->status = Task::STATUS_CANCELLED;
        $task->save();
        return responder()->success();
    }

    public function stat()
    {
        return responder()->success([
            'total' => Task::count(),
            'initialized_num' => Task::whereIn('status', [Task::STATUS_INITIALIZED, Task::STATUS_CANCELLED])->count(),
            'progressing_num' => Task::where('status', Task::STATUS_PROGRESSING)->count(),
            'completed_num' => Task::where('status', Task::STATUS_COMPLETED)->count(),
            'postponed_num' => Task::where('status', Task::STATUS_POSTPONED)->count(),
        ]);
    }

    public function fireAggregate(Request $request)
    {
        $request->validate([
            'id' => 'required|integer|exists:tasks,id,deleted_at,NULL',
        ]);
        if (!Auth::user()->hasPermissionTo('task-publish')) {
            throw new AuthException();
        }
        $task = Task::find($request->id);
        if ($task->status != Task::STATUS_COMPLETED) {
            // throw new AppException('任务状态不正确');
        }
        TaskService::finishTask($task);
        return responder()->success(['msg' => $task->name . ' 创建汇总队列任务']);
    }
}
